/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.svh.Hibernate;

import com.svh.Paginator.IPaginacion;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;

/**
 *
 * @author Luis Alonso Ballena Garcia
 * @param <T>
 */
public abstract class HibernatePaginator<T> implements IPaginacion<T>{
    
    protected DetachedCriteria filtroCriteria = null;
    
    protected DetachedCriteria totalCriteria = null;
    
    protected DetachedCriteria listCriteria = null;
    
    protected DetachedCriteria allListCriteria = null;
   
    
    protected IConexionHibernate conexion;
    
    
    public HibernatePaginator() {
        
    }
    
    public abstract void initFiltro();

    public  void setConexion(IConexionHibernate conexion){
        this.conexion = conexion;
    }
    
    
    @Override
    public int getTotalRows(){
        int totalRows =0;
        totalCriteria.setProjection(Projections.rowCount());
        totalRows = ((Long)(totalCriteria.getExecutableCriteria(conexion.getSession()).uniqueResult())).intValue();
        return totalRows;
    }
    
    @Override
    public List<T> getListElementsForPage(int first, int pageSize) {
        List<T> auxLista = new ArrayList<T>();
        auxLista = listCriteria.getExecutableCriteria(conexion.getSession()).setFirstResult(first).setMaxResults(pageSize).list();
        return auxLista;
    }

    @Override
    public List<T> allList(){
        return allListCriteria.getExecutableCriteria(conexion.getSession()).list();
    }
    
    public void cloneCriteria(){
        try{
            this.totalCriteria = copyDetachedCriteria(filtroCriteria);
            this.listCriteria = copyDetachedCriteria(filtroCriteria);
            this.allListCriteria = copyDetachedCriteria(filtroCriteria);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    private DetachedCriteria copyDetachedCriteria(DetachedCriteria detachedCriteria) throws IOException, ClassNotFoundException {
        try {
            ByteArrayOutputStream baostream = new ByteArrayOutputStream();
            ObjectOutputStream oostream = new ObjectOutputStream(baostream);
            oostream.writeObject(detachedCriteria);
            oostream.flush();
            oostream.close();
            ByteArrayInputStream baistream = new ByteArrayInputStream(baostream.toByteArray());
            ObjectInputStream oistream = new ObjectInputStream(baistream);
            DetachedCriteria copy = (DetachedCriteria) oistream.readObject();
            oistream.close();
            return copy;
        } catch (IOException e) {
            throw e;
        } catch (ClassNotFoundException e) {
            throw e;
        }
    }
    
    /****/
    
    public DetachedCriteria getFiltroCriteria() {
        return filtroCriteria;
    }

    public void setFiltroCriteria(DetachedCriteria filtroCriteria) {
        this.filtroCriteria = filtroCriteria;
    }

    
    
    
    
}
